package com.asj.vivo.lock.service.updateService;


import static com.asj.enums.DeviceIdentifierDictEnums.appVersionNumber;
import static com.asj.enums.DeviceIdentifierDictEnums.appVersionUpdateUrl;
import static com.asj.enums.DeviceIdentifierDictEnums.json_key_code;
import static com.asj.enums.DeviceIdentifierDictEnums.json_key_deviceCode;
import static com.asj.enums.DeviceIdentifierDictEnums.json_key_message;
import static com.asj.enums.HttpRequestDictEnums.findLastedVersionUrl;
import static com.asj.enums.ResultCodeEnums.result_success;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.DownloadManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.core.content.FileProvider;

import com.asj.MainActivity;
import com.asj.R;
import com.asj.service.AllocationPageService;
import com.asj.service.oppoSdk.OPPOSDKService;
import com.asj.service.request.RequestMDMService;
import com.asj.utils.CommonsUtils;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 更新app版本服务
 * */
public class UpdateAppVersionService {
    private static long lastDownloadedBytes = 0; // 上一次下载的字节数
    private static long totalBytes = 0; // 总字节数
    private static long downloadedBytes = 0; // 已下载的字节数
    private static long startTime = 0; // 下载开始时间

    private static String versionNumber;

    public static MainActivity mainActivity;

    /**
     * 更新版本记录
     * */
    public static final Map<Integer,String> updateStep = new HashMap<>();

    //查询最新的appVersion信息，返回boolean值判断是否存在更新
    public static void queryAppVersion(MainActivity mainActivity){
        //异步获取是否有更新的版本
        AtomicReference<String> responseData = new AtomicReference<>();
        new Thread(()->{
            try {
                JsonObject requestData = new JsonObject();
                //获取本地版本号
                String localVersion = mainActivity.getPackageManager().getPackageInfo(mainActivity.getPackageName(), 0).versionName;
                requestData.addProperty("appVersion",localVersion);
                requestData.addProperty("manufacturersCode","OPPO");
                requestData.addProperty(json_key_deviceCode.getValue(),CommonsUtils.getDeviceCode(new OPPOSDKService(mainActivity).getIMEI()));
                //发送请求获取数据
                responseData.set(RequestMDMService.sendResult(requestData.toString(), findLastedVersionUrl.getValue()));
            } catch (IOException | PackageManager.NameNotFoundException e) {
                throw new RuntimeException(e);
            }

            AlertDialog.Builder builder = new AlertDialog.Builder(mainActivity);
            if(responseData.get() == null || responseData.get().isEmpty()){
                //获取后台应用更新信息异常，进行通知提示
                CommonsUtils.showNotification(mainActivity,"应用更新情况未知","获取后台的更新信息失败");

                builder.setCancelable(false);
                builder.setTitle("应用错误！");
                builder.setMessage("后台获取数据失败！是否继续进行运行应用?");
                builder.setPositiveButton("继续", (dialog, which) -> {
                    //更新到最新版本才允许走绑定流程
                    AllocationPageService.coreLoad(mainActivity);
                });
                // 设置"退出"按钮
                builder.setNegativeButton("退出", (dialog, which) -> {
                    // 关闭所有活动并退出应用
                    mainActivity.finishAffinity();
                    System.exit(0);
                });
                mainActivity.runOnUiThread(()->{
                    builder.create().show();
                });
            }else{
                //解析第一步，得到最外层的Result对象
                JsonObject result = JsonParser.parseString(responseData.get()).getAsJsonObject();
                //解析第二步，判断返回的code是不是200
                int code = result.get(json_key_code.getValue()).getAsInt();
                if(result_success.getCode() == code){
                    //解析第三步，获取其中的message信息，是否包含isLastedVersionOK
                    boolean message = result.get(json_key_message.getValue()).getAsString().equals("isLastedVersionOK");
                    //如果不等于isLastedVersionOK则说明，存在更新
                    if(!message){
                        //获取更新数据
                        JsonObject lockAppVersion = JsonParser.parseString(result.get("result").getAsString()).getAsJsonObject();
                        versionNumber = lockAppVersion.get("versionNumber").getAsString();
                        String updateUrl = lockAppVersion.get("updateUrl").getAsString();
                        //更新开始
                        updateApkVersion(mainActivity,updateUrl);
                    }else{
                        //更新到最新版本才允许走绑定流程
                        AllocationPageService.coreLoad(mainActivity);
                    }
                }else{
                    builder.setCancelable(false);
                    String message = result.get("message").getAsString();
                    builder.setTitle(message.split(",")[0]);
                    builder.setMessage(message.split(",")[1]);
                    builder.setPositiveButton("知道了", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            // 关闭所有活动并退出应用
                            mainActivity.finishAffinity();
                            System.exit(0);
                        }
                    });
                    mainActivity.runOnUiThread(()->{
                        builder.create().show();
                    });
                }
            }
        }).start();
    }

    /**
     * 指定版本推送更新
     * */
    public static void assignVersionUpdate(Context context,JsonObject appVersionUpdate){
        versionNumber = appVersionUpdate.get(appVersionNumber.getValue()).getAsString();
        String updateUrl = appVersionUpdate.get(appVersionUpdateUrl.getValue()).getAsString();
        updateStep.put(1,"获取版本完毕，更新开始");
        //更新开始
        updateApkVersion(context,updateUrl);
    }




    /**
     * 更新第一步：下载apk
     * */
    public static void updateApkVersion(Context context, String updateUrl) {
        //获取下载管理器
        DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
        //发送下载请求
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(updateUrl));

        //设置通知栏中的浮窗的
        request.setTitle("更新 " + context.getPackageName()); //下载的标题
        request.setDescription("正在下载更新..."); //  设置下载描述

        //编辑下载文件的文件名
        String fileName = versionNumber + ".apk";
        // 设置下载的文件路径
        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
        // 设置可见性为可见，这样用户可以在下载列表中看到
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

        updateStep.put(2,"开始下载apk");

        // 将下载的APK加入下载队列，开始下载，获取下载ID
        long downloadId = downloadManager.enqueue(request);
        //进行app内的更新可视化弹窗的创建
        if(mainActivity != null){
            updateDownloadProgress(downloadId,mainActivity);
        }
    }

    /**
     * 更新第一步中的第一步：创建可视化弹窗，让用户能够看到下载进度
     * */
    private static void updateDownloadProgress(final long downloadId, MainActivity mainActivity) {
        //初始化进度组件
        new Thread(() -> {
            // 在下载开始时初始化变量
            startTime = System.currentTimeMillis();
            lastDownloadedBytes = 0;
            showProgressDialog(mainActivity);
            while (true) {
                //获取已下载大小，下载文件的总大小，下载状态
                final int[] status = getDownloadStatus((DownloadManager) mainActivity.getSystemService(Context.DOWNLOAD_SERVICE), downloadId);
                //计算比值，更新进度条等组件的显示
                queryDownloadStatus(mainActivity,downloadId);
                //状态更新，下载完毕
                if (status[2] == DownloadManager.STATUS_SUCCESSFUL || status[2] == DownloadManager.STATUS_FAILED) {
                    //将下载框去除，加载安装框
                    downloadCompleted(mainActivity);
                    break;
                }
            }
        }).start();
    }

    private static AlertDialog progressDialog;

    /**
     * 更新第一步中的第二步：设置下载时的弹出框
     * */
    private static void showProgressDialog(MainActivity mainActivity) {
        mainActivity.runOnUiThread(()->{
            progressDialog = new AlertDialog.Builder(mainActivity)
                    .setTitle("下载更新")
                    .setMessage("正在下载最新版本...")
                    .setView(R.layout.custom_progress_view)
                    .setCancelable(false)
                    .create();
            progressDialog.show();
        });
    }

    /**
     * 查询已下载的字节数，总字节数,下载状态
     * status[0]：已下载的字节数，表示从开始下载到现在为止已经下载了多少数据。
     * status[1]：总字节数，表示下载文件的总大小。
     * status[2]：下载状态，是一个整数，代表下载任务的当前状态，可以是以下几个值之一：
     * DownloadManager.STATUS_PENDING：等待开始下载。
     * DownloadManager.STATUS_RUNNING：下载正在进行中。
     * DownloadManager.STATUS_PAUSED：下载已暂停。
     * DownloadManager.STATUS_SUCCESSFUL：下载成功完成。
     * DownloadManager.STATUS_FAILED：下载失败。
     * */
    @SuppressLint("Range")
    private static int[] getDownloadStatus(DownloadManager downloadManager, long downloadId) {
        DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
        Cursor cursor = downloadManager.query(query);
        int[] status = new int[3];
        if (cursor.moveToFirst()) {
            // 获取到目前为止已下载的字节数，并将其存储在status数组的第一个位置
            status[0] = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
            // 获取下载文件的总字节数，并将其存储在status数组的第二个位置
            status[1] = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
            // 获取下载任务的当前状态，并将其存储在status数组的第三个位置
            // 状态可能是：等待、运行中、暂停、成功或失败
            status[2] = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
        }
        cursor.close();
        return status;
    }

    /**
     * 关闭下载框
     * */
    private static void downloadCompleted(MainActivity mainActivity) {
        if (progressDialog != null) {
            progressDialog.dismiss();
        }
        updateStep.put(3,"下载完毕，开始安装");
        showInstallDialog(mainActivity);
    }

    /**
     * 展示安装框
     * */
    private static void showInstallDialog(MainActivity mainActivity) {
        mainActivity.runOnUiThread(()->{
            new AlertDialog.Builder(mainActivity)
                    .setTitle("下载完成")
                    .setMessage("是否立即安装更新？")
                    .setPositiveButton("安装", (dialog, which) -> {
                        updateStep.put(4,"用户确认安装");
                        installApp(mainActivity);
                    })
                    .setNegativeButton("取消", (dialog, which) -> {
                        new AlertDialog.Builder(mainActivity)
                            .setTitle("警告")
                            .setMessage("如果取消安装的话则可能存在某些安全漏洞，是否取消？如果确认取消，系统将自动退出应用")
                            .setPositiveButton("继续安装", (dialog2, which2) -> {
                                installApp(mainActivity);
                            })
                            .setNegativeButton("确认取消", (dialog2, which2) -> {
                                // 关闭所有活动并退出应用
                                mainActivity.finishAffinity();
                                System.exit(0);
                            })
                        .show();
                    })
                    .show();
        });
    }

    public static void installApp(MainActivity mainActivity){
        // 启动安装流程
        String fileName = versionNumber + ".apk";
        File apkFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName);
        if (apkFile.exists()) {
            Intent installIntent = new Intent();
            installIntent.setAction(Intent.ACTION_VIEW);

            Uri apkUri = FileProvider.getUriForFile(mainActivity, "com.asj.provider", apkFile);

            installIntent.setDataAndType(apkUri, "application/vnd.android.package-archive");
            installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            mainActivity.startActivity(installIntent);
        } else {
            Toast.makeText(mainActivity, "APK文件不存在！", Toast.LENGTH_SHORT).show();
        }
    }

    // 定期查询下载状态
    @SuppressLint({"DefaultLocale", "SetTextI18n"})
    public static void queryDownloadStatus(MainActivity mainActivity, long downloadId) {
        int[] status = getDownloadStatus((DownloadManager) mainActivity.getSystemService(Context.DOWNLOAD_SERVICE), downloadId);
        downloadedBytes = status[0]; // 已下载的字节数
        totalBytes = status[1]; // 总字节数

        // 计算下载速率
        long currentTime = System.currentTimeMillis();
        long timeElapsed = currentTime - startTime;
        long bytesDownloadedSinceLastCheck = downloadedBytes - lastDownloadedBytes;

        // 初始化下载速率持有者
        DownloadSpeedHolder downloadSpeedHolder = new DownloadSpeedHolder();
        // 在更新 UI 的地方，使用 lambda 表达式
        downloadSpeedHolder.updateSpeed((timeElapsed > 0) ? (double) (bytesDownloadedSinceLastCheck * 1000) / timeElapsed : downloadSpeedHolder.getSpeed());


        lastDownloadedBytes = downloadedBytes;

        // 计算传输比值
        double ratio = (double) downloadedBytes / totalBytes;
        // 计算百分比
        int percentage = (int) (ratio * 100);

        // 更新UI
        mainActivity.runOnUiThread(() -> {
            ProgressBar customProgressBar = progressDialog.findViewById(R.id.custom_progressBar);
            TextView currentProgressText = progressDialog.findViewById(R.id.currentProgressText);
            TextView currentSpeedText = progressDialog.findViewById(R.id.currentSpeedText);
            TextView currentTransferRatioText = progressDialog.findViewById(R.id.currentTransferRatioText);

            // 使用更新后的下载速率设置文本
            currentSpeedText.setText(String.format("当前下载速率：%,.2f Mb/s", downloadSpeedHolder.getSpeed() / (1024 * 1024)));
            //更新传输比
            currentTransferRatioText.setText(String.format("已下载大小：%d Mb/总大小：%d Mb", downloadedBytes / (1024 * 1024), totalBytes / (1024 * 1024)));
            //更新进度条
            customProgressBar.setProgress(percentage);
            //更新百分比文字数据
            currentProgressText.setText("当前进度条进度:"+percentage+"%");
        });
    }

    // 创建一个容器类来持有下载速率
    final static class DownloadSpeedHolder {
        double speed = 0;

        public void updateSpeed(double newSpeed) {
            this.speed = newSpeed;
        }

        public double getSpeed() {
            return this.speed;
        }
    }



}
